<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Writing BHF Components</title>
    <base href="http://bhs.googlecode.com/svn/trunk/"><!--[if IE]></base><![endif]-->
</head>
<body bgcolor="white">
<h1>Writing Components</h1>
<h2>A Component Is A?</h2>
<p>
    A Component is Service with state and events. Since a Component has state, one Component may be different than
    another Component; thus, Components must have IDs to identify a particular Component, of a class of
    Components, of interest. In some sense, Service method are like static Methods and Component methods like
    object methods. You only need the class to invoke a static method, but you need the context of a particular
    object to invoke an object method.
</p><p>
    BHF is RESTful in the since that it requires no server side state: all state is in the client and is transferred
    to the server as needed. Of course, moving state back and forth between the client and server can be a performance
    issue: both the marhsalling/unmarshalling costs and network delays. We've taken care of the marshaling/unmarshalling
    issue, at least on the server side, by providing a
    <a href="javadocs/org/bhf/json/package-summary.html">high performance JSON implementation</a>. To improve network
    performance, BHF provides server side caching of Component state. If you turn on server side caching for
    a Component, the state of the Component is preserved bewteen calls in a memory sensitive cache. (This allows the
    cache to release entries when memory is tight.) Because the cache is not a guarantee that the Component state is
    still server side, the client has to try the call without passing state and retry the call with state on a cache
    miss. Clearly, you do not want to routinely make two calls over the network so you should only use server side
    caching as an optimization technique when the situation warrants, such as large Components (state-wise) that are
    not modified client side. (If you modify the Component state client side, the server clearly will not have the
    correct state in cache.)
</p><p>
    How does the server know if you changed the state client side? Only with your help. Each Component has a version
    number that you must increment if you modify the Component: client side <em>or</em> server side, for that matter.
    On the client side you can increment the version as follows:
    <code>myComponent.state.version++;</code>
    On the server side, assuming you are extending <code>AbstractComponent</code> the version will be increment with
    each successful method invocation, unless you call <code>notChanged()</code>.
</p><p><a href="javadocs/org/bhf/json/package-summary.html">You should understand the BHF JSON library</a> and
   <a href="writing-services.html">how to write Services</a> before writing Components.
</p>
<h2>Component</h2>
Looking at the example calculator Component code, below, you see that a Component looks almost exactly like a Service.
The key difference are the <code>ComponentInfo</code> annotation and the event interface. You use
<code>ComponentInfo</code> to specify whether to use server side caching (default is to not cache) and the events
issues by this <code>Component</code>, if any. Note that you must include the <code>ServiceName</code> annotation
to give the <code>Component</code> a name.
<pre><code>
package example;

import org.bhf.service.ServiceName;
import org.bhf.service.ServiceMethod;
import org.bhf.component.ComponentInfo;
import org.bhf.component.AbstractComponent;
import org.bhf.component.EventQueue;

@ServiceName( "calculator" )
@ComponentInfo( eventGroup = Calculator.CalculatorEvents.class )
public class Calculator extends AbstractComponent
{
    private double              currentValue;
    private CalculatorEvents    events = EventQueue.getNewQueue( Calculator.CalculatorEvents.class );

    public double getCurrentValue()
    {
        return currentValue;
    }

    public void setCurrentValue( final double currentValue )
    {
        this.currentValue = currentValue;
    }

    @ServiceMethod
    public void     add( final double x )
    {
        currentValue += x;
        events.update();
    }

    @ServiceMethod
    public void     sub( final double x )
    {
        currentValue -= x;
        events.update();
    }

    @ServiceMethod
    public void     div( final double x )
    {
        currentValue /= x;
        events.update();
    }

    @ServiceMethod
    public void     mul( final double x )
    {
        currentValue *= x;
        events.update();
    }

    @ServiceMethod
    public void     clear()
    {
        currentValue = 0;
        events.update();
    }

    /**
     * This interface defines the events that Calculator supports. It MUST match the eventGroup parameter of
     * ComponentInfo.
     */
    interface CalculatorEvents
    {
        void    update();
    }
}
</code></pre>

<h2>Events</h2>
<p>
    Component events build on the Yahoo! Event Utility, so you should be familiar with Custom Events before using
    events with your Components. <code>ComponentInfo.eventGroup</code> specifies an interface that implies the
    set of events issued by your Component. Each operation of the interface becomes a Custom Event on the  Component.
    This inference is used only by code generators, such as the BHF <code>component</code> JSP tag, that introspect
    a Component in order to generate the JavaScript for the Component.
</p><p>
    To queue events, call <code>EventQueue.getNewQueue( myEventGroup );</code>, where <code>myEventGroup</code> is
    your Event Group (which should match your <code>ComponentInfo</code> attribute) and invoke the event operations
    on the supplied object. Each operation will queue a single event to be dispatched, in order, when control returns
    to the client side. Events can take arguments to be passed to the event handlers. (Note that multiple arguments
    in Java will appear as an array of arguments in your handler: a minor quirk to the Yahoo! Custom Events or Java,
    depending on your point of view.) As is the case with all objects passed between the client and server, the
    events arguments must be well behaved with respect to JSOn marshalling and unmarshalling.
</p>

<p>See also: <a href="../../bhf/www/docs/calling-components.html">Calling Components</a></p>
</body>
</html>